﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpMedia
{
    public class TripTrigger
    {
        public event EventHandler TimeOut;
        public event EventHandler FirstTrigger;
        public event EventHandler ReTriggered;
        private TimeSpan time;

        public TimeSpan Time
        {
            get { return time; }
            set { time = value; }
        }

        private TimeSpan timeLeft = TimeSpan.MaxValue;

        public bool Triggered { get { return timeLeft != TimeSpan.MaxValue; } }

        public void Trigger()
        {
            if (timeLeft == TimeSpan.MaxValue && FirstTrigger != null)
                FirstTrigger(this, EventArgs.Empty);

            if (timeLeft != TimeSpan.MaxValue && ReTriggered != null)
                ReTriggered(this, EventArgs.Empty);

            timeLeft = time;
        }

        public TripTrigger(TimeSpan time)
        {
            this.time = time;
        }

        public void Update(TimeSpan ts)
        {

            if (timeLeft == TimeSpan.MaxValue || TimeOut == null)
                return;

            timeLeft -= ts;

            if (timeLeft <= TimeSpan.Zero)
            {
                timeLeft = TimeSpan.MaxValue;
                TimeOut(this, EventArgs.Empty);
            }
        }

        public void Stop(bool triggerTimeOut)
        {
            timeLeft = TimeSpan.MaxValue;
            if (triggerTimeOut)
            {
                TimeOut(this, EventArgs.Empty);
            }

        }
    }


    public class TimedTrigger<T>
    {
        public event EventHandler TimeOut;
        public event EventHandler FirstTrigger;
        public event EventHandler ReTriggered;
        private TimeSpan time;

        public TimeSpan Time
        {
            get { return time; }
            set { time = value; }
        }

        private DateTime lastTrigger = DateTime.MinValue;

        private T stateVar;

        public T StateVar
        {
            get
            {
                return stateVar;
            }
            set
            {
                stateVar = value;
                Trigger();
            }
        }

        public bool Triggered { get { return lastTrigger != DateTime.MinValue; } }

        public void Reset(T resetState) { this.stateVar = resetState; }

        public void Trigger()
        {
            if (lastTrigger == DateTime.MinValue && FirstTrigger != null)
                FirstTrigger(this, EventArgs.Empty);

            if (lastTrigger != DateTime.MinValue && ReTriggered != null)
                ReTriggered(this, EventArgs.Empty);

            lastTrigger = DateTime.Now;
        }

        public TimedTrigger(T state, TimeSpan time)
        {
            this.stateVar = state;
            this.time = time;
        }

        public void Update()
        {
            if (lastTrigger == DateTime.MinValue || TimeOut == null)
                return;

            if (DateTime.Now.Subtract(lastTrigger) > time)
            {
                lastTrigger = DateTime.MinValue;
                TimeOut(this, EventArgs.Empty);
            }
        }

        public void Stop(bool triggerTimeOut)
        {
            lastTrigger = DateTime.MinValue;
            if (triggerTimeOut)
            {
                TimeOut(this, EventArgs.Empty);
            }

        }

    }
}
